package cn.zn.sync.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.zn.dept.entity.SysCorp;
import cn.zn.dept.entity.SysDept;
import cn.zn.dept.mapper.SysCorpMapper;
import cn.zn.dept.mapper.SysDeptMapper;
import cn.zn.dept.service.SysDeptService;
import cn.zn.sync.constants.SyncConstants;
import cn.zn.sync.service.OrgSyncService;
import cn.zn.sync.utils.SyncUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class OrgSyncServiceImpl implements OrgSyncService {

    private final Logger logger = LoggerFactory.getLogger(OrgSyncServiceImpl.class);

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private SysDeptService deptService;

    @Autowired
    private SysCorpMapper corpMapper;

    @Override
    public void orgAllSync() {
        Date start = new Date();

        ExecutorService executorService = Executors.newFixedThreadPool(5);

        int pageSize = 1000;

        String password = SyncUtil.sign(SyncConstants.CODE, SyncConstants.SALT);
        String resBody = SyncUtil.requestApi(SyncConstants.ORG_URL, password, 1, pageSize, null);
        JSONObject json = SyncUtil.getJson(resBody);
        executorService.execute(() -> saveOrg(json));

        int total = json.getInt("total");
        int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        // 从第二页开始
        for (int i = 2; i <= totalPage; i++) {
            resBody = SyncUtil.requestApi(SyncConstants.ORG_URL, password, i, pageSize, null);
            JSONObject json1 = SyncUtil.getJson(resBody);
            executorService.execute(() -> saveOrg(json1));
        }

        executorService.shutdown();
        while (true) {
            if (executorService.isTerminated()) {
                deptService.refreshDeptCache();

                Date end = new Date();
                logger.info("组织全量同步结束, 开始时间：" + DateUtil.format(start, "yyyy-MM-dd HH:mm:ss") + "，结束时间：" + DateUtil.format(end, "yyyy-MM-dd HH:mm:ss") + "，耗时：" + DateUtil.betweenMs(start, end) + "MS");
                break;
            }
        }
    }

    @Override
    public void orgIncrementSync() {
        Date start = new Date();

        ExecutorService executorService = Executors.newFixedThreadPool(5);

        String latestTs = deptMapper.selectLatestTs();
        Map<String, Object> searchParams = new HashMap<>();
        searchParams.put("startdate", latestTs);
        searchParams.put("iseffect", "Y,N");

        int pageSize = 1000;

        String password = SyncUtil.sign(SyncConstants.CODE, SyncConstants.SALT);
        String resBody = SyncUtil.requestApi(SyncConstants.ORG_URL, password, 1, pageSize, searchParams);
        JSONObject json = SyncUtil.getJson(resBody);
        executorService.execute(() -> saveOrg(json));

        int total = json.getInt("total");
        int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        // 从第二页开始
        for (int i = 2; i <= totalPage; i++) {
            resBody = SyncUtil.requestApi(SyncConstants.ORG_URL, password, i, pageSize, searchParams);
            JSONObject json1 = SyncUtil.getJson(resBody);
            executorService.execute(() -> saveOrg(json1));
        }

        executorService.shutdown();
        while (true) {
            if (executorService.isTerminated()) {
                deptService.refreshDeptCache();

                Date end = new Date();
                logger.info("组织增量同步结束, 开始时间：" + DateUtil.format(start, "yyyy-MM-dd HH:mm:ss") + "，结束时间：" + DateUtil.format(end, "yyyy-MM-dd HH:mm:ss") + "，耗时：" + DateUtil.betweenMs(start, end) + "MS");
                break;
            }
        }
    }

    /**
     * 保存组织
     *
     * @param json 组织
     */
    private void saveOrg(JSONObject json) {
        JSONArray data = json.getJSONArray("data");
        if (data != null && data.size() > 0) {
            for (int i = 0; i < data.size(); i++) {
                JSONObject orgJson = data.getJSONObject(i);
                SysDept org = new SysDept();
                org.setId(orgJson.getStr("pk_org"));
                org.setCode(orgJson.getStr("code")); // 组织编号
                org.setName(orgJson.getStr("name")); // 组织名
                org.setShortName(orgJson.getStr("shortname")); // 组织简称
                org.setParentId(orgJson.getStr("pk_fatherorg")); // 上级组织
                org.setParentCode(orgJson.getStr("fatherorg_code")); // 上级组织
                org.setParentName(orgJson.getStr("fatherorg_name")); // 上级组织

                String corp = StrUtil.trim(orgJson.getStr("corp_name"));
                org.setCorp(corp); // 产业
                if (StrUtil.isNotBlank(corp)) {
                    SysCorp sysCorp = corpMapper.selectCorpByName(corp);
                    org.setCorpId(sysCorp != null ? sysCorp.getId() : null); // 产业
                }

                org.setFzrCode(orgJson.getStr("fzrcode")); // 部门负责人
                org.setFzrName(orgJson.getStr("fzrname")); // 部门负责人
                org.setFgCode(orgJson.getStr("fgcode")); // 分管领导
                org.setFgName(orgJson.getStr("fgname")); // 分管领导
                org.setBzflag(orgJson.getStr("bzflag")); // 组织类型：z组织；b部门
                org.setStatus(orgJson.getStr("iseffect")); // 状态（y正常 n停用）
                org.setTs(DateUtil.parse(orgJson.getStr("ts"), "yyyy-MM-dd HH:mm:ss")); // nc更新时间
                org.setModifyBy("api");
                org.setModifyTime(new Date());
                try {
                    if ("N".equals(org.getStatus())) {
                        // 如果状态为禁用，只做更新
                        org.updateById();
                    } else {
                        QueryWrapper<SysDept> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("id", org.getId());
                        int count = deptMapper.selectCount(queryWrapper);
                        if (count > 0) {
                            org.updateById();
                        } else {
                            org.setCreateBy("api");
                            org.setCreateTime(new Date());
                            org.insert();
                        }
                    }
                } catch (Exception e) {
                    logger.error("组织保存失败：" + e.getMessage());
                }
            }
        }
    }

}
